#include <AVUITransform.h>

namespace AVUI {

/// <summary>Scales an object in the 2-D x-y coordinate system. </summary>
class ScaleTransform : public Transform
{
public:
    DECLARE_ELEMENT(ScaleTransform, Transform);

#pragma region Public Methods

    /// <summary>Initializes a new instance of the <see cref="T:System.Windows.Media.ScaleTransform" /> class. </summary>
    ScaleTransform() { };

    /// <summary>Initializes a new instance of the <see cref="T:System.Windows.Media.ScaleTransform" /> class with the specified x- and y- scale factors. The scale operation is centered on (0,0). </summary>
    /// <param name="scaleX">The x-axis scale factor.</param>
    /// <param name="scaleY">The y-axis scale factor.</param>
    ScaleTransform(float sx, float sy);

    /// <summary>Initializes a new instance of the <see cref="T:System.Windows.Media.ScaleTransform" /> class that has the specified scale factors and center point.</summary>
    /// <param name="scaleX">The x-axis scale factor. For more information, see the <see cref="P:System.Windows.Media.ScaleTransform.ScaleX" /> property.</param>
    /// <param name="scaleY">The y-axis scale factor. For more information, see the <see cref="P:System.Windows.Media.ScaleTransform.ScaleY" /> property.</param>
    /// <param name="centerX">The x-coordinate of the center of this <see cref="T:System.Windows.Media.ScaleTransform" />. For more information, see the <see cref="P:System.Windows.Media.ScaleTransform.CenterX" /> property.</param>
    /// <param name="centerY">The y-coordinate of the center of this <see cref="T:System.Windows.Media.ScaleTransform" />. For more information, see the <see cref="P:System.Windows.Media.ScaleTransform.CenterY" /> property.</param>
    ScaleTransform(float scaleX, float scaleY, float centerX, float centerY);

    /// <summary>Creates a modifiable copy of this <see cref="T:System.Windows.Media.ScaleTransform" /> by making deep copies of its values. </summary>
    /// <returns>A modifiable deep copy of the current object. The <see cref="P:System.Windows.Freezable.IsFrozen" /> property of the cloned object returns false even if the <see cref="P:System.Windows.Freezable.IsFrozen" /> property of the source is true.</returns>
    TRefCountedPtr<ScaleTransform> Clone() { return (ScaleTransform*) Transform::Clone().get_Ptr(); }

    /// <summary>Creates a modifiable copy of this <see cref="T:System.Windows.Media.ScaleTransform" /> object by making deep copies of its values. This method does not copy resource references, data bindings, or animations, although it does copy their current values. </summary>
    /// <returns>A modifiable deep copy of the current object. The <see cref="P:System.Windows.Freezable.IsFrozen" /> property of the cloned object is false even if the <see cref="P:System.Windows.Freezable.IsFrozen" /> property of the source is true.</returns>
    TRefCountedPtr<ScaleTransform> CloneCurrentValue() { return (ScaleTransform*) Transform::CloneCurrentValue().get_Ptr(); }

#pragma endregion Public Methods

#pragma region Public Properties

    /// <summary>Gets or sets the x-coordinate of the center point of this <see cref="T:System.Windows.Media.ScaleTransform" />. This is a dependency property. </summary>
    /// <returns>The x-coordinate of the center point of this <see cref="T:System.Windows.Media.ScaleTransform" />. The default is 0.</returns>
    float get_CenterX() { return AVUI::UnboxValue<float>(GetValue(get_CenterXProperty())); }
    void set_CenterX(float value) { SetValue(get_CenterXProperty(), AVUI::BoxValue(value)); } 
    DECLARE_DEPENDENCY_PROPERTY(CenterX);

    /// <summary>Gets or sets the y-coordinate of the center point of this <see cref="T:System.Windows.Media.ScaleTransform" />. This is a dependency property. </summary>
    /// <returns>The y-coordinate of the center point of this <see cref="T:System.Windows.Media.ScaleTransform" />. The default is 0.</returns>
    float get_CenterY() { return AVUI::UnboxValue<float>(GetValue(get_CenterYProperty())); }
    void set_CenterY(float value) { SetValue(get_CenterYProperty(), AVUI::BoxValue(value)); } 
    DECLARE_DEPENDENCY_PROPERTY(CenterY);

    /// <summary>Gets or sets the x-axis scale factor. This is a dependency property. </summary>
    /// <returns>The scale factor along the x-axis. The default is 1.</returns>
    float get_ScaleX() { return AVUI::UnboxValue<float>(GetValue(get_ScaleXProperty())); }
    void set_ScaleX(float value) { SetValue(get_ScaleXProperty(), AVUI::BoxValue(value)); } 
    DECLARE_DEPENDENCY_PROPERTY(ScaleX);

    /// <summary>Gets or sets the y-axis scale factor. This is a dependency property. </summary>
    /// <returns>The scale factor along the y-axis. The default is 1.</returns>
    float get_ScaleY() { return AVUI::UnboxValue<float>(GetValue(get_ScaleYProperty())); }
    void set_ScaleY(float value) { SetValue(get_ScaleYProperty(), AVUI::BoxValue(value)); } 
    DECLARE_DEPENDENCY_PROPERTY(ScaleY);

    virtual Matrix get_Value() AVUI_OVERRIDE;

#pragma endregion Public Properties

protected:
#pragma region Protected Properties
    virtual TRefCountedPtr<Freezable> CreateInstanceCore() AVUI_OVERRIDE { return object_allocate<ScaleTransform>().get_Ptr(); }
#pragma endregion Protected Properties

public:

#pragma region Internal Methods

    virtual void MultiplyValueByMatrix(Matrix* pResult, const Matrix& matrixToMultiplyBy);
    virtual void TransformRect(Rect* pRect);

#pragma endregion Internal Methods

#pragma region Internal Properties

    virtual bool get_IsIdentity() AVUI_OVERRIDE;

#pragma endregion Internal Properties

private:

#pragma region Private Methods

    static void StaticConstructor();

#pragma endregion Private Methods

};


typedef TRefCountedPtr<ScaleTransform> ScaleTransformPtr;


}; // namespace AVUI
